package com.example.xmind2testcase.service;

import com.alibaba.druid.support.json.JSONParser;
import com.example.xmind2testcase.exportdata.TestCaseExportData;
import com.example.xmind2testcase.mapper.FileMapper;
import com.example.xmind2testcase.mapper.TestcaseMapper;
import com.example.xmind2testcase.mapper.TestplainCaseMapper;
import com.example.xmind2testcase.mapper.XmindMapper;
import com.example.xmind2testcase.pojo.Testcase;
import com.example.xmind2testcase.pojo.TestplainTestcase;
import com.example.xmind2testcase.pojo.Xmind;
import com.example.xmind2testcase.pojo.XmindNode;
import com.example.xmind2testcase.pojo.vo.CaseVo;
import com.example.xmind2testcase.vo.TestcaseVo;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import org.xmind.core.*;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.URLEncoder;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class TestcaseManageServiceImpl implements TestcaseManageService{
    @Autowired
    private XmindMapper xmindMapper;

    @Autowired
    private TestcaseMapper testcaseMapper;

    @Autowired
    private TestplainCaseMapper testplainCaseMapper;

    @Autowired
    private FileMapper fileMapper;

    @Override
    public String saveTestcase(TestcaseVo tv) {
        Xmind xmind = tv.getXmind();
        List<Testcase> listT = tv.getTestcases();
        Xmind xmindData = xmindMapper.getXmindData(xmind.getFileId());

        //如果没有保存过
        if(xmindData == null){
            //保存xmind文件
            xmindMapper.addXmind(xmind);
            return "保存成功";
        }
        xmindMapper.updateXmind(xmind);
        return "保存成功";
    }

    @Override
    public TestcaseVo getTestcase(Long fileId){
        TestcaseVo testcaseVo = new TestcaseVo();
        Xmind xmindData = xmindMapper.getXmindData(fileId);
        List<Testcase> testcase = testcaseMapper.getTestcase(fileId);
        testcaseVo.setTestcases(testcase);
        testcaseVo.setXmind(xmindData);
        return testcaseVo;
    }

    @Override
    public Integer updateTestcase(List<Testcase> testcaseList) {
        for (Testcase ts:testcaseList) {
            testcaseMapper.updateTestcaseDesc(ts);
        }
        return null;
    }

    @Override
    public Integer add2TestPlain(List<String> testcaseList,Long testPlainId,Long fileId){
//
        ArrayList<TestplainTestcase> testplainTestcases = new ArrayList<>();
        //
        Set<String> insertTestcase = testcaseList.stream().map(item->item).collect(Collectors.toSet());
        List<Testcase> testcase1 = testcaseMapper.getTestcase(fileId);

        //要插入的测试用例
        List<Testcase> collect = testcase1.stream().filter(item -> insertTestcase.contains(item.getId())).collect(Collectors.toList());
        for (Testcase testcase:collect) {
            TestplainTestcase testplainTestcase = new TestplainTestcase();
            testplainTestcase.setPlainId(testPlainId);
            testplainTestcase.setDescription(testcase.getDescription());
            testplainTestcase.setTitle(testcase.getTitle());
            testplainTestcases.add(testplainTestcase);
        }
        //加入测试计划
        Integer integer = testplainCaseMapper.addTestplainCaseBath(testplainTestcases);
        return integer;


    }

    @Override
    public List<TestplainTestcase> getTestcasePlain(Long plainId) {
        List<TestplainTestcase> testcasePlain = testplainCaseMapper.getTestcasePlain(plainId);
        return testcasePlain;
    }

    @Override
    public List<TestCaseExportData> exportTestcaseExcel(List<CaseVo> testcaseVos) throws JsonProcessingException {
//        List<TestplainTestcase> testcasePlainById = testplainCaseMapper.getTestcasePlainById(caseId);
        ArrayList<TestCaseExportData> testCaseExportData = new ArrayList<>();

        for(int i=0;i<testcaseVos.size();i++){
            CaseVo caseVo = testcaseVos.get(i);
            TestCaseExportData testCaseExportData1 = new TestCaseExportData();
            testCaseExportData1.setTitle(caseVo.getTitle());
            testCaseExportData1.setCaseDesignPhase(caseVo.getCaseDesignPhare());
            testCaseExportData1.setCaseType(caseVo.getCaseType());
            testCaseExportData1.setDesigner(caseVo.getDesigner());
            testCaseExportData.add(testCaseExportData1);
            ArrayList<Map<String, String>> steps = caseVo.getSteps();
            for (Map<String,String> step: steps) {
                TestCaseExportData testCaseExportData2 = new TestCaseExportData();
                String stepString = step.get("step");
                String result = step.get("result");
                testCaseExportData2.setStep(stepString);
                testCaseExportData2.setResult(result);
                testCaseExportData.add(testCaseExportData2);
            }
        }
//        System.out.println(testCaseExportData);
        return testCaseExportData;
    }

    @Override
    public ArrayList<HashMap<String, Object>> translateXmind2Testcase(Long fileID) {
        Xmind xmindData = xmindMapper.getXmindData(fileID);
        String mind = xmindData.getMind();
        JSONParser jsonParser = new JSONParser(mind);
        Map<String, Object> stringObjectMap = jsonParser.parseMap();
        LinkedHashMap<String,Object> data = (LinkedHashMap<String, Object>) stringObjectMap.get("data");
        HashMap<String, ArrayList> stringArrayListHashMap = new HashMap<>();
        analysisXmind(data,"",stringArrayListHashMap);

        Set<String> strings = stringArrayListHashMap.keySet();
        ArrayList<HashMap<String, Object>> hashMaps = new ArrayList<>();
        for(String key:strings){
            HashMap<String, Object> stringObjectHashMap = new HashMap<>();
            stringObjectHashMap.put("title",key);
            ArrayList arrayList = stringArrayListHashMap.get(key);
            ArrayList<HashMap<String, String>> hashMaps1 = new ArrayList<>();
            if(arrayList == null){

            }else {

                for(int i =0;i<arrayList.size();i++){
                    HashMap<String,String> o = (HashMap<String, String>) arrayList.get(i);
                    HashMap<String, String> stringStringHashMap = new HashMap<>();
                    stringStringHashMap.put("step",o.get("step"));
                    if(o.containsKey("result")&&o.get("result")!=null){
                        stringStringHashMap.put("result",o.get("result"));
                    }else {
                        stringStringHashMap.put("result","");
                    }
                    hashMaps1.add(stringStringHashMap);
                }
            }
            stringObjectHashMap.put("steps",hashMaps1);
            hashMaps.add(stringObjectHashMap);

        }

        return hashMaps;
    }

    @Override
    public void downloadXmind(long fileId, HttpServletResponse response) {
        Xmind xmindData = xmindMapper.getXmindData(fileId);
        String mind = xmindData.getMind();
        JSONParser jsonParser = new JSONParser(mind);
        Map<String, Object> stringObjectMap = jsonParser.parseMap();
        LinkedHashMap<String,Object> data = (LinkedHashMap<String, Object>) stringObjectMap.get("data");

        ObjectMapper objectMapper = new ObjectMapper();
        XmindNode xmindNode=null;

        try {
            String jsonString = objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(data);
            xmindNode = objectMapper.readValue(jsonString, XmindNode.class);
        }catch (JsonProcessingException e){
            e.printStackTrace();
            throw new RuntimeException("json解析失败");

        }
        IWorkbook iWorkbook = xmindFileBuilt(xmindNode);
        exportXmind(iWorkbook,"xmind测试用例.xmind",response);
    }

    @Override
    public String uploadFile(MultipartFile file) {
//        InputStream inputStream = file.getInputStream();

        return "success";
    }

    @Override
    public String deleteFile(Long fileId) {
        xmindMapper.deleteXmind(fileId);
        fileMapper.deleteFile(fileId);
        return "success";
    }

    public IWorkbook xmindFileBuilt(XmindNode xmindNode){
        IWorkbookBuilder workbookBuilder = Core.getWorkbookBuilder();
        IWorkbook workbook = workbookBuilder.createWorkbook();
        ISheet primarySheet = workbook.getPrimarySheet();
        ITopic rootTopic = primarySheet.getRootTopic();
        // 设置根主题的标题
        String topic = xmindNode.getTopic();
        rootTopic.setTitleText(topic);
        xmindPhaseBuilt(workbook,rootTopic,xmindNode);
        return workbook;


    }

    public void exportXmind(IWorkbook workbook,String fileName,HttpServletResponse response){
        try {
            response.setCharacterEncoding("UTF-8");
            response.setHeader("content-Type", "application/xmind");
            response.setHeader("Content-Disposition",
                    "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8"));
            workbook.save(response.getOutputStream());

        } catch (IOException | CoreException e) {
            throw new RuntimeException(e.getMessage());
        }

    }

    private void xmindPhaseBuilt(IWorkbook workbook,ITopic topic,XmindNode xmindNode) {
        if(xmindNode.getChildren()!=null){
            for(XmindNode xmindNode1: xmindNode.getChildren()){
                String topicText = xmindNode1.getTopic();
                ITopic topic1 = workbook.createTopic();
                topic1.setTitleText(topicText);
                topic.add(topic1,ITopic.ATTACHED);
                xmindPhaseBuilt(workbook,topic1,xmindNode1);
            }
        }else {
            return;
        }
    }

    public void analysisXmind2List(){

    }

    public void analysisXmind(LinkedHashMap<String,Object> linkedHashMap, String topic, HashMap<String,ArrayList> hashMap){

        String topic1 = (String) linkedHashMap.get("topic");
        if("步骤".equals(topic1)){
            if(linkedHashMap.containsKey("children")){
                ArrayList<LinkedHashMap<String,Object>> children = (ArrayList<LinkedHashMap<String, Object>>) linkedHashMap.get("children");
                ArrayList<HashMap> hashMaps = new ArrayList<>();
                for (LinkedHashMap<String,Object> child: children) {
                    String step = (String) child.get("topic");
                    String result1="";
                    HashMap<String, String> stringStringHashMap = new HashMap<>();
                    if(child.containsKey("children")){
                        ArrayList<Object> children1 = (ArrayList<Object>) child.get("children");
                        if(children1.size()==1){
                            LinkedHashMap<String,Object> o = (LinkedHashMap<String, Object>) children1.get(0);
                            result1 = (String) o.get("topic");
                        }else {
                            for(int i= 0;i<children1.size();i++){
                                LinkedHashMap<String,Object> o = (LinkedHashMap<String, Object>) children1.get(i);
                                String result = (String) o.get("topic");
                                if(i== children1.size()-1){
                                    result= i+":"+result;
                                }else {
                                    result= i+":"+result+"\r\n";
                                }

                                result1 = result1+result;
                            }
                        }
                    }
                    stringStringHashMap.put("step",step);
                    stringStringHashMap.put("result",result1);
                    hashMaps.add(stringStringHashMap);

                }
                hashMap.put(topic,hashMaps);
                return;
            }
        }else {
            if(linkedHashMap.containsKey("children")){
                    ArrayList<LinkedHashMap<String,Object>> children = (ArrayList<LinkedHashMap<String, Object>>) linkedHashMap.get("children");
                    for(LinkedHashMap<String,Object> child: children){
                        analysisXmind(child,topic+"-"+topic1,hashMap);
                    }
            }else {
                topic1 = topic + "-" + topic1;
                hashMap.put(topic1, null);
                return;
            }
        }
    }
}
